home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Python / dynload_mac.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  3.2 KB  |  118 lines

  1. /* Support for dynamic loading of extension modules */
  2.  
  3. #include "Python.h"
  4. #include "importdl.h"
  5.  
  6. #include <Aliases.h>
  7. #include <CodeFragments.h>
  8. #ifdef SYMANTEC__CFM68K__ /* Really an older version of Universal Headers */
  9. #define CFragConnectionID ConnectionID
  10. #define kLoadCFrag 0x01
  11. #endif
  12. #ifdef USE_GUSI1
  13. #include "TFileSpec.h"        /* for Path2FSSpec() */
  14. #endif
  15. #include <Files.h>
  16. #include "macdefs.h"
  17. #include "macglue.h"
  18.  
  19.  
  20. const struct filedescr _PyImport_DynLoadFiletab[] = {
  21.     {".slb", "rb", C_EXTENSION},
  22. #ifdef __CFM68K__
  23.     {".CFM68K.slb", "rb", C_EXTENSION},
  24. #else
  25.     {".ppc.slb", "rb", C_EXTENSION},
  26. #endif
  27.     {0, 0}
  28. };
  29.  
  30.  
  31. dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
  32.                     const char *pathname, FILE *fp)
  33. {
  34.     dl_funcptr p;
  35.     char funcname[258];
  36.  
  37.     /*
  38.     ** Dynamic loading of CFM shared libraries on the Mac.  The
  39.     ** code has become more convoluted than it was, because we
  40.     ** want to be able to put multiple modules in a single
  41.     ** file. For this reason, we have to determine the fragment
  42.     ** name, and we cannot use the library entry point but we have
  43.     ** to locate the correct init routine "by hand".
  44.     */
  45.     FSSpec libspec;
  46.     CFragConnectionID connID;
  47.     Ptr mainAddr;
  48.     Str255 errMessage;
  49.     OSErr err;
  50. #ifndef USE_GUSI1
  51.     Boolean isfolder, didsomething;
  52. #endif
  53.     char buf[512];
  54.     Str63 fragname;
  55.     Ptr symAddr;
  56.     CFragSymbolClass class;
  57.         
  58.     /* First resolve any aliases to find the real file */
  59. #ifdef USE_GUSI1
  60.     err = Path2FSSpec(pathname, &libspec);
  61. #else
  62.     (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
  63.     err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
  64. #endif
  65.     if ( err ) {
  66.         sprintf(buf, "%.255s: %.200s",
  67.             pathname, PyMac_StrError(err));
  68.         PyErr_SetString(PyExc_ImportError, buf);
  69.         return NULL;
  70.     }
  71.     /* Next, determine the fragment name,
  72.        by stripping '.slb' and 'module' */
  73.     memcpy(fragname+1, libspec.name+1, libspec.name[0]);
  74.     fragname[0] = libspec.name[0];
  75.     if( strncmp((char *)(fragname+1+fragname[0]-4),
  76.             ".slb", 4) == 0 )
  77.         fragname[0] -= 4;
  78.     if ( strncmp((char *)(fragname+1+fragname[0]-6),
  79.              "module", 6) == 0 )
  80.         fragname[0] -= 6;
  81.     /* Load the fragment
  82.        (or return the connID if it is already loaded */
  83.     err = GetDiskFragment(&libspec, 0, 0, fragname, 
  84.                   kLoadCFrag, &connID, &mainAddr,
  85.                   errMessage);
  86.     if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) {
  87.         /*
  88.         ** Special-case code: if PythonCore is too old or too new this means
  89.         ** the dynamic module was meant for a different Python.
  90.         */
  91.         if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) {
  92.             sprintf(buf, "Dynamic module was built for %s version of MacPython",
  93.                 (err == cfragImportTooOldErr ? "a newer" : "an older"));
  94.             PyErr_SetString(PyExc_ImportError, buf);
  95.             return NULL;
  96.         }
  97.     }
  98.     if ( err ) {
  99.         sprintf(buf, "%.*s: %.200s",
  100.             errMessage[0], errMessage+1,
  101.             PyMac_StrError(err));
  102.         PyErr_SetString(PyExc_ImportError, buf);
  103.         return NULL;
  104.     }
  105.     /* Locate the address of the correct init function */
  106.     sprintf(funcname, "init%.200s", shortname);
  107.     err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
  108.     if ( err ) {
  109.         sprintf(buf, "%s: %.200s",
  110.             funcname, PyMac_StrError(err));
  111.         PyErr_SetString(PyExc_ImportError, buf);
  112.         return NULL;
  113.     }
  114.     p = (dl_funcptr)symAddr;
  115.  
  116.     return p;
  117. }
  118.